package multiThread;

import java.net.URL;

/**
 * Holds the buffers for the visited and unvisited URLS.
 * @author Darin Cyr
 * @author Kirk Leonard
 * @author John Patanian
 * @version Autumn 2009
 */
public class URLBucket
{
  /**
   * The maximum number of unvisited pages that
   * can be put into the buffer.
   */
  private static final int MAX_CAPACITY = 100;
  
  /**
* Holds the urls that have been already visited.
 */
  private Buffer<URL> my_visited_urls;
  
  /**
   * Holds the urls that have not yet been visited.
   */
  private Buffer<URL> my_unvisited_urls;
  
  /**
   * 
   */
  public URLBucket()
  {
    my_visited_urls = new Buffer<URL>();
    my_unvisited_urls = new Buffer<URL>();
  }
  
  /**
   * Adds a url to the unvisited list.
   * @param the_url The URL to add to the list.
   * @throws InterruptedException Rethrows this exception.
   */
  public synchronized void add(final URL the_url) throws InterruptedException
  {
    /**
     * Wait if the buffer is completely full
     */
    
    while (my_unvisited_urls.size() == MAX_CAPACITY)
    {
      try
      {
        wait();
      }
      catch (final InterruptedException e)
      {
        throw e;
      }
    }
    my_unvisited_urls.add(the_url);
    notify();
  }
  
  /**
   * Gets a URL from the unvisited list.
   * Adds to the visited list if not a duplicate.
   * @return Returns a URL
   * @throws InterruptedException An interrupted Exception.
   */
  public synchronized URL get() throws InterruptedException
  {
  //wait till something appears in the buffer
    while (my_unvisited_urls.isEmpty())  
    {  
      try 
      {   
        wait(); 
      }
      catch (final InterruptedException e) 
      {
        throw e;
      }
    }    
    final URL url = my_unvisited_urls.get();
    if (url != null && !my_visited_urls.contains(url))
    {
      my_visited_urls.add(url);

    }
    notify();   
    return url;
  } 
  
  /**
   * The number of sites visited in total.
   * @return the size
   */
  public int getNumVisited()
  {
    return my_visited_urls.size();
  }
  
  /**
   * Current size of the unvisited sites.
   * @return the size.
   */
  public int getNumUnvisited()
  {
	  return my_unvisited_urls.size();
  }
}
